﻿using System;
using System.Reflection;
using Shell.PocoDot;
using System.Collections.Generic;
using System.Linq;

namespace Framework.Domain
{
    public static class PocoUtils
    {
        public static void AssignProperty<T>(T from, T to, params Type[] denyTypes) where T : PocoDotBase
        {
            Type type = typeof(T);
            var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(i => i.CanWrite && i.CanRead).AsParallel();
            properties.ForAll((property) =>
            {
                if (property.Name != "Id") //TODO
                {
                    var isAllow = true;
                    foreach (var denyType in denyTypes)
                    {
                        if (denyType.Equals(property.DeclaringType))
                        {
                            isAllow = false;
                            break;
                        }
                    }
                    if (isAllow)
                    {
                        var original = property.GetValue(from, null);
                        property.SetValue(to, original, null);
                    }
                }
            });
        }

        private static ParallelQuery<PropertyInfo> GetProperties(Type type)
        {
            List<PropertyInfo> properties = new List<PropertyInfo>();
            if (type.BaseType != typeof(Object))
            {
                properties.AddRange(GetProperties(type.BaseType));
            }
            var innerProperties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(i => i.CanWrite && i.CanRead && !properties.Any(p => p.Name == i.Name)).AsParallel();
            properties.AddRange(innerProperties);
            return properties.AsParallel();
        }
    }
}
